package com.cindata

import grails.transaction.Transactional

@Transactional
class AccountFlowStageEventService
{
    ComponentService componentService

    def initFlowStageEvent(Account account, Workflow workflow)
    {
        def workflowStages = WorkflowStage.findAllByWorkflow(workflow)
        for (
            workflowStage in
                workflowStages)
        {
            workflowStage?.events?.each {
                def accountFlowStageEvent = new AccountFlowStageEvent()
                accountFlowStageEvent.isSynchronous = it?.isSynchronous
                accountFlowStageEvent.executeSequence = it?.executeSequence
                accountFlowStageEvent.log = it?.log
                accountFlowStageEvent.component = it?.component
                accountFlowStageEvent.flowStage = AccountFlowStage.findByAccountAndStage(account, workflowStage?.stage)
                if (accountFlowStageEvent.validate())
                {
                    accountFlowStageEvent.save flush: true
                }
                else
                {
                    println accountFlowStageEvent.errors
                }
            }
        }
    }

    def evaluate(AccountFlowStage flowStage, String executeSequence)
    {
        def events = []
        if (executeSequence == 'positive')
        {
            events = AccountFlowStageEvent.findAll("from AccountFlowStageEvent where flowStage.id = ${flowStage?.id} and executeSequence > 0 order by executeSequence ASC")
        }
        else if (executeSequence == 'negative')
        {
            events = AccountFlowStageEvent.findAll("from AccountFlowStageEvent where flowStage.id = ${flowStage?.id} and executeSequence < 0 order by executeSequence ASC")
        }
        if (events?.size() > 0)
        {
            events?.each {
                def event = it
                if (event?.isSynchronous)
                {
                    evaluate2(event)
                }
                else
                {
                    Thread.start {
                        evaluate2(event)
                    }
                }
            }
        }
    }

    def evaluate2(AccountFlowStageEvent eventObject)
    {
        def shell = new GroovyShell()
        def closure
        def result
        def event = AccountFlowStageEvent.find("from AccountFlowStageEvent where id = ${eventObject?.id}")

        try
        {
            event.startTime = new Date()
            if (event?.component)
            {
                result = componentService.evaluate event?.component, event?.flowStage?.account
            }
            event.log = result
            event.endTime = new Date()
            event.save flush: true
        }
        catch (Exception e)
        {
            event.log = e
            event.endTime = new Date()
            event.save flush: true
        }
    }
}